
/**
 * 游戏场景会话
 * @class SceneSession
 * @summary 逻辑场景的启动入口, 单例对象
 * @example
let ss = require('SceneSession').share()
ss.addTimer({}=>{})
 */

let mCallbackIndex = 0

class SceneSession 
{

    static mInstance = null

    static share() 
    {
        if (!this.mInstance) 
        {
            this.mInstance = new SceneSession()
        }
        return this.mInstance
    }

    init() 
    {
        this.mScene = null

        this.mRoot = cc.director.getScene()

        let vm = require('ViewMan').share()
        vm.init()
    }

    /**
     * 启动游戏入口界面，开始游戏循环
     * @private
     */
    go() 
    {
        let vm = require('ViewMan').share()
        // vm.translate('AssetUpdateView')
        vm.translate('LoginView')

        this.startLoop()
    }

    /**
     * 通过场景对象或者名称进行加载并初始化
     *
     * @param {String} scene - 场景对象或者名称
     * @param {String} scenePrefab - 场景依赖的预制名称, 如果为空，参数scene必须为String
     * @param {Function} callback - 加载结果回调
     */

    loadScene(scene, scenePrefab, callback) 
    {
        let sce = null

        if (typeof(scene) == 'string')
        {
            let Scene = require(scene)
            sce = new Scene()
        }
        else// if (typeof(scene) == 'object')
        {
            sce = scene
        }

        this.mScenePrefab = 'prefabs/' + (scenePrefab || scene)

        ogre.loadPrefab(this.mScenePrefab, 10, 
            (res) => {

                if (res) 
                {
                    let root = cc.instantiate(res)
                    if (root)
                    {
                        if (1)
                        {
                            cc.find('Canvas').addChild(root)
                        }
                        else
                        {
                            this.mRoot.addChild(root)
                        }
                        

                        this.mScene = sce
                        
                        this.mScene.init(root,
                            (ok)=>{

                                callback(this.mScene)
                            }
                        )
                        return
                    }
                }

                sce = null

                callback()
            }
        )        
    }

    /**
     * 销毁当前运行的逻辑场景
     */
    destroyScene() 
    {
        if (this.mScene) 
        {
            this.mScene.destroy()
            this.mScene = null

            ogre.releasePrefab(this.mScenePrefab)
        }
    }

    /**
     * 启动游戏循环，场景创建成功需要逻辑循环时调用
     *
     * @param {number} time_per_frame_mis - 逻辑帧间隔时间，毫秒；默认游戏每秒执行20次
     */
    startLoop(time_per_frame_mis)
    {
        if (!this.mRoot)
        {
            return
        }

        this.stopLoop()

        //let tpf = time_per_frame_mis || 60

        let delta = 0

        this.mLooper = (dt)=> {

            delta = dt * 1000
            
            if (this.mScene)
            {
                this.mScene.update(delta)
            }

            this.updateTimers(delta)
        }
        cc.director.getScheduler().schedule(this.mLooper, this.mRoot, -1)
        //cc.director.getScheduler().schedule(this.mLooper, this.mRoot, tpf/1000)
    }

    /**
     * 停止游戏循环调用
     */
    stopLoop()
    {
        if (!this.mRoot)
        {
            return
        }

        if (this.mLooper)
        {
            cc.director.getScheduler().unschedule(this.mLooper, this.mRoot)

            //clearInterval(this.mLooper)
            this.mLooper = null
        }
    }

    /**
     * 添加定时器回调
     *
     * @param {Function} callback(delta) - 回调
     * @param {number} delay - 延时多少毫秒执行一次回调, 如果为空，callback 每次游戏循环都会执行，知道callback内部返回值true结束
     */
    addTimer(callback, delay) 
    {
        let i = ++mCallbackIndex

        let d = {

            delay    : delay,
            callback : callback,
            id       : i
        }

        if (this.mTimers)
        {
            this.mTimers.push(d)
        }
        else
        {
            this.mTimers = [d]
        }
        return i
    }

    /**
     * 移除定时器
     */
    removeTimer(id) 
    {
        if (this.mTimers)
        {
            let num = this.mTimers.length
            for (let i = 0; i < num; ++i)
            {
                if (this.mTimers[i].id == id)
                {
                    this.mTimers.splice(i, 1)

                    return true
                }
            }
        }
        return false
    }

    /**
     * 移除所有的定时器
     */
    removeAllTimers() 
    {
        if (this.mTimers)
        {
            this.mTimers = null
        }
    }

    updateTimers(tpf)
    {
        if (!this.mTimers)
        {
            return
        }

        let num = this.mTimers.length
        if (num === 0)
        {
            return
        }

        let i = 0, v = null
        while( i < num)
        {
            v = this.mTimers[i]
            if (v.delay != null && v.delay != undefined)
            {
                v.delay -= tpf

                if (v.delay <= 0)
                {
                    v.callback(tpf)

                    this.mTimers.splice(i, 1)
                    --num
                }
                else
                {
                    ++i
                }
            }
            else
            {
                if (v.callback(tpf))
                {
                    this.mTimers.splice(i, 1)
                    --num
                }
                else
                {
                    ++i
                }
            }
        }
    }

    /**
     * 返回当前运行的逻辑场景类对象
     */
    sceneBy() 
    {    
        return this.mScene
    }

    /**
     * 返回当前运行cc.Scene对象
     */
    rootBy() 
    {
        return this.mRoot
    }
}

export default SceneSession 
